home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PAS_0693 / RDASCIIZ.PAS < prev    next >
Pascal/Delphi Source File  |  1993-06-30  |  3KB  |  76 lines

  1. {─ Fido Pascal Conference ────────────────────────────────────────────── PASCAL ─
  2. Msg  : 462 of 474
  3. From : Dj Murdoch                          1:249/99.5           27 Jun 93  08:12
  4. To   : Todd Holmes
  5. Subj : Unit Cstr: Nul term strings for streams
  6. ────────────────────────────────────────────────────────────────────────────────
  7.  TH>  Cstr is a unit to suppliment the writing and reading of Nul terminating
  8.  TH>  strings to and from Streams. Cstr also offers conversion
  9.  TH> from Pascal strings
  10.  TH>  to Nul term Strings.
  11.  
  12.  TH> Function LoadCStr(Var S:TStream): PChar;
  13.  TH> var
  14.  TH>  Start,Stop: LongInt;
  15.  TH>  L: Word;
  16.  TH>  Buf: Char;
  17.  TH>  CStr: PChar;
  18.  TH> begin
  19.  TH>   Start := S.GetPos;
  20.  TH>   Repeat              {Scan for end of string, (nul term char: #0)
  21.  TH>     S.Read(Buf,1);    no need for a larger buffer, since were using
  22.  TH>                        TBufStream with a 1 k buffer
  23.  TH>   Until Buf = #0;
  24.  TH>   Stop := S.GetPos;
  25.  TH>   if (stop - Start) > MaxLen then LoadCStr := Nil {string is to big!
  26.  TH>                       {Needs additon error checking here
  27.  TH>   Else
  28.  TH>     begin
  29.  TH>      L := Stop - Start; {Get Length of string, include nul terminator
  30.  TH>      GetMem(CStr,L);    {Allocate memory
  31.  TH>      S.Seek(Start);     {repostion
  32.  TH>      S.Read(CStr^,L);   {Read the string
  33.  TH>      LoadCStr := CStr;
  34.  TH>     end;
  35.  TH> end; {LoadCstr}
  36. {
  37. The trouble with this kind of approach is that it's really slow, and doesn't
  38. work on streams that don't support Seek.  Even if you're using something like
  39. TBufStream that does support Seek, it's a very slow operation:  every call to
  40. Seek flushes the buffer, and the next read will reload it all from disk.  So,
  41. for example, to read a series of 3 character null-terminated strings, you'd do
  42. a 1K read to reload the buffer on *every* call to LoadCStr.
  43.  
  44. I don't know a good way to read Asciiz strings, but I think it's worth
  45. requiring the caller to supply the buffer:  at least then you only have to make
  46. one pass through the file, and if it's a buffered stream, you don't flush the
  47. buffer.  You might want to offer that *in addition* to the LoadCStr procedure,
  48. because sometimes the caller knows an adequate buffer size, and sometimes it
  49. doesn't.
  50.  
  51. Here's the one I use:}
  52.  
  53.  function ReadAsciiz(S : PStream;var Buffer;MaxLen:word):Word;
  54.  var
  55.    size  : word;
  56.    streamsize : longint;
  57.    c : char;
  58.    resultbytes : TByteArray absolute buffer;
  59.  begin
  60.    size := 0;
  61.    c := #1;
  62.    while (c <> #0) and (size < Maxlen) and (S^.Status = stOK) do
  63.    begin
  64.      S^.Read(c,1);
  65.      resultbytes[size] := byte(c);
  66.      inc(size);
  67.    end;
  68.    if c <> #0 then
  69.    begin
  70.      resultbytes[size] := 0;
  71.      s^.Reset;
  72.    end
  73.    else
  74.      dec(size);
  75.    ReadAsciiz := size;
  76.  end;